from utils.handle_attribute import HandleAttr
from utils.handle_phone import HandlePhone
from utils.handle_log import log,log_tojson
from utils.handle_ini import conf
from utils.handle_db import orcl
import ast
class HandleReplace:

    def __set_attribute(self,key,val):
        setattr(HandleAttr,key,val)
    #通过handle_phone生成未注册过的手机号
    def __get_data_by_script(self,key):
        phone = HandlePhone().get_phone()
        log.info(msg=f'通过脚本生成未注册过的手机号为：{phone}')
        self.__set_attribute(key=key,val=phone)
        log.info(msg=f'将该手机号设置为类属性{key}={phone}')

    #从配置文件读取手机号和密码
    def __get_data_by_conf(self,key):
        user_info = conf.get(section="USER",option=key)
        log.info(msg=f'通过配置文件拿到的信息为：{user_info}')
        self.__set_attribute(key=key,val=user_info)
        log.info(msg=f'将配置文件取出的账号密码写入字典并保存为类属性：{key}={user_info}')

    def __get_data_by_db(self,key,sql):
        # 支持多个参数
        data = orcl.get_db_all_data(sql)
        log.info(msg="从db中获取到的数据:{}".format(data))

        # for val in data[0].values():
        #     self.__set_attribute(key=key, val=val)
        #     log.info(msg="将db中获取到的数据，并设置为类属性:{}={}".format(key, val))
        val = data[0][0]
        self.__set_attribute(key=key, val=val)
        log.info(msg=f"将db中获取到的数据，并设置为类属性:{key}={val}")

    def __replace_data(self,data,key_list):
        """
        使用字符串replace方法替换请求参数
        :param data:
               :type=str
               excel中的请求参数data
        :param key_list:
               :type=list
               需要替换的key的list
        :return: str
        """
        log.info(msg="==============开始请求入参参数替换==============")
        if isinstance(data,str):
            data = data
        else:
            data = str(data)
        log.info(msg="替换之前的参数:\n{},类型为{}".format(log_tojson(data),type(data)))
        for key in key_list:
            data = data.replace(f"#{key}#",str(getattr(HandleAttr,key)))
        log.info(msg="==============参数替换结束==============")
        return data

    def replace_request_data(self, request_data, replace_request_data):
        """
        :param request_data:
                type = dict,str
                接口请求参数
        :param replace_request_data:
               type = str
               {"mobile_phone":["db","select mobile_phone from  member where type=0 order by id desc limit 1"]}
               {"mobile_phone":["conf1"]}
               {"mobile_phone":["script"]}
               {"mobile_phone":["attribute"]}
        :return:
               :type=dict
        """
        try:
            log.info(msg='参数替换传入请求参数：\n{}，类型为：{}'.format(log_tojson(request_data),type(request_data)))
            log.info(msg='参数替换传入请求参数替换规则：\n{},类型为：{}'.format(log_tojson(replace_request_data),type(replace_request_data)))
            if request_data and replace_request_data:
                # 从参数替换规则中拿到需要替换参数的key
                replace_request_data = ast.literal_eval(replace_request_data)
                log.info(msg="请求参数替换规则类型转换后\n{},类型为：{}".format(log_tojson(replace_request_data),type(replace_request_data)))
                replace_key_list = [key for key in replace_request_data.keys()] #replace_key_list = ['mobilephone','password']
                log.info(msg="请求参数中需要替换的参数key列表\n{}".format(replace_key_list))
                for key,val in replace_request_data.items():
                    # (mobilephone,["conf"])
                    if val[0].lower() == "conf":
                        log.info(msg="从conf配置文件获取需要替换的参数，并设置为类属性:{}".format(key))
                        # 如果list中第一个标记位，为conf,就说明这个参数需要从配置文件去获取,取出来之后就设置为类属性
                        self.__get_data_by_conf(key=key)
                    elif val[0].lower() == "script":
                        if key == "mobilephone": # 替换随机生成的手机号，未注册过的
                            log.info(msg="脚本替换未注册过的手机号，并设置为类属性:{}".format(val[0]))
                            self.__get_data_by_script(key=key)
                        else:
                            log.info(msg="脚本替换只支持手机号，不支持该参数的脚本替换，参数替换时不做任何处理:{}".format(val[0]))
                    elif val[0].lower() == "attribute":
                        log.info(msg="该参数已在类属性中，不需要再设置类属性，参数替换的时候可以直接拿:{}".format(val[0]))
                    elif val[0].lower() == "db":
                        if len(val) == 2:
                            log.info(msg="从数据库获取需要替换的参数，并设置为类属性:{}".format(val[0]))
                            self.__get_data_by_db(key=key,sql=val[1])
                        else:
                            log.info(msg="参数替换规则有误，没有写sql语句,传入的参数替换规则为:\n{}".format(log_tojson(replace_request_data)))
                    else:
                        log.info(msg="不支持改替换场景，检查标记位,传入的参数替换规则为:\n{}".format(log_tojson(replace_request_data)))
                # 从这里开始做参数替换
                new_request_data_by_str = self.__replace_data(data=request_data, key_list=replace_key_list)
                log.info(msg="替换后的请求参数为:\n{}，类型为{}".format(log_tojson(new_request_data_by_str),type(ast.literal_eval(new_request_data_by_str))))
                return ast.literal_eval(new_request_data_by_str)
            elif request_data and not replace_request_data:
                log.info(msg="参数替换规则为空，不需要做参数替换,将传入的请求参数转换成dict再返回:\n{},类型为:{}".format(log_tojson(request_data),type(ast.literal_eval(request_data))))
                return ast.literal_eval(request_data)
            else:
                log.info(msg="请求参数和参数替换规则都为空，不需要替换参数，返回空字典")
                return {}
        except Exception as e:
            log.exception(e)
            raise Exception("replace_request_data请求参数替换执行报错")



